package com.qi.demo01.Singleton;

/**
 * @author zjq
 * @date 2020/3/30 20:09
 */

/**
 * 懒汉式 单线程ok，多线程并发下不安全
 */
public class LazyMan {
    //创建自己的唯一实例
    private volatile static LazyMan lazyMan;

    //构造器私有
    private LazyMan() {
        System.out.println(Thread.currentThread().getName() + "======OK");
    }

    //双层检测锁的模式，懒汉式单例 DCL懒汉式
    private static LazyMan getInstance() {
        if (lazyMan == null) {
            synchronized (LazyMan.class) {
                if (lazyMan == null) {
                    lazyMan = new LazyMan();//他不是原子性操作
                    /**
                     * 步骤：
                     * 1.分配内存空间
                     * 2.执行构造方法，初始化对象，
                     * 3.把这个对象指向这个空间
                     */

                    //有可能执行指令重排
                    //123
                    //132  A线程没有问题，但是B线程会认为此事lazyman！=null 执行return 然后此时B的lazyman什么都没有。 所以要用Volatile保证原子性。
                    //会出现
                }

            }
        }
        return lazyMan;

    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                LazyMan.getInstance();
            }).start();
        }
    }
}
